import axios, { AxiosRequestConfig } from "axios";

const request = axios.create({
  baseURL: "http://localhost:3000/",
});

// 请求拦截器
request.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("access_token");
    if (token) {
      config.headers.Authorization = `${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 刷新token
const refreshToken = async () => {
  const refreshToken = localStorage.getItem("refresh_token");
  if (!refreshToken) {
    return Promise.reject("refresh_token is empty");
  }

  // 这里会等到并发的请求都执行完之后再执行
  const res = await request.get(`user/refresh?refreshToken=${refreshToken}`);

  return res.data;
};

interface PendingTask {
  config: AxiosRequestConfig;
  resolve: Function;
}
// 是否还需要刷新token的标识
let refreshing = false;
// 存储未完成的请求
const task: PendingTask[] = [];

// 响应拦截器
request.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    const { data, config } = error.response;

    // 如果正在刷新token，则将失败的请求挂起,
    // 存入task中等待刷新token完成在全部执行出来
    if (refreshing) {
      return new Promise((resolve) => {
        task.push({
          config,
          resolve,
        });
      });
    }

    // 如果是登录过期并且请求的地址不是 /user/refresh，就调用refreshToken
    if (data.statusCode === 401 && config.url !== "/user/refresh") {
      // 此时需要刷新了
      refreshing = true;
      try {
        const res = await refreshToken();
        // 刷新token成功
        refreshing = false;

        // 重新发送请求
        task.forEach((item) => {
          item.resolve(request(item.config));
        });

        localStorage.setItem("access_token", res.data.access_token);
        localStorage.setItem("refresh_token", res.data.refresh_token);

        return request(config);
      } catch (error) {
        // refreshToken失败，跳转到登录页
        // ......
      }
    }
    return Promise.reject(error);
  }
);
export default request;
